#!/usr/bin/env bash
#
# Phalcon
# Copyright (c) 2011-2017 Phalcon Team (https://phalconphp.com)
#
# This source file is subject to the New BSD License that is bundled
# with this package in the file LICENSE.txt.
#
# If you did not receive a copy of the license and are unable to
# obtain it through the world-wide-web, please send an email
# to license@phalconphp.com so we can send you a copy immediately.
#

CURRENT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
WORK_DIR=${CURRENT_DIR}

GIT_BIN=$(command -v git 2>/dev/null)
PHP_BIN=$(command -v php 2>/dev/null)
COMPOSER_BIN=$(command -v composer 2>/dev/null)

DOCS_REPO=https://github.com/phalcon/docs

if [ -f .env ]; then
    source .env
fi

ST_OK=0
ST_ERR=1
ST_HLP=2

GREEN="\033[0;32m"
RED="\033[0;31m"
YELLOW="\e[1;33m"
PURPLE="\e[0;35m"
NC="\033[0m"

INSTALL_DEPS=1
UPDATE_DOCS=1
PULL_CHANGES=1
CLEAR_CACHE=1

VERSION=0.12.2
APP_NAME="Phalcon Docs"

print_version() {
    printf "${YELLOW}${APP_NAME} Deployer${NC} v${VERSION}\n"
    printf "Copyright (c) 2011-2017 Phalcon Team (https://phalconphp.com)\n\n"
}

print_dump_version() {
    printf "${VERSION}\n"
}

print_help() {
    printf "\n${YELLOW}Usage:${NC}"
    printf "\n./deploy [options]\n"
    printf "\n${YELLOW}Options:${NC}"
    printf "\n      ${GREEN}--[no-]install-deps${NC}        Install the application dependencies using the Composer (enabled by default)"
    printf "\n      ${GREEN}--[no-]update-docs${NC}         Update the documentation for all known versions (enabled by default)"
    printf "\n      ${GREEN}--[no-]pull-changes${NC}        Pull the latests changes from the git repo (enabled by default)"
    printf "\n      ${GREEN}--[no-]clear-cache${NC}         Clear the cache (enabled by default)"
    printf "\n  ${GREEN}-L, --list-versions${NC}            List known docs versions"
    printf "\n  ${GREEN}-H, --help${NC}                     Show this help message"
    printf "\n  ${GREEN}-V, --version${NC}                  Show the version and exit"
    printf "\n      ${GREEN}--dumpversion${NC}              Show only version number and exit"
    printf "\n      ${GREEN}--working-dir=WORKING-DIR${NC}  If specified, use the given directory as working directory"
    printf "\n"
    printf "\n${YELLOW}Help:${NC}"
    printf "\n${APP_NAME} Deployer is a source code deploying script."
    printf "\n\n"
}

print_unknown_option() {
    print_error "Unknown option: ${1}." >&2
    print_error "See ./deploy --help for more."
}

print_error() {
    printf "${RED}Error: ${1}${NC}\n"
}

print_loales_dirs() {
    find $(pwd) -maxdepth 1 -type d | grep -v ".git" | grep -v "^.$" | awk -F$(pwd) '{print $2;}' | grep -v "^$" | awk -F'^/' '{print $2;}'
}

validate_work_dir() {
    if [[ ! -d  ${WORK_DIR} ]]; then
        print_error "Unable to locate specified path as working directory: ${WORK_DIR}. Exit..."
        exit ${ST_ERR}
    fi
}

validate_versions() {
    if [[ ! -f "${WORK_DIR}/VERSIONS" ]]; then
        echo -e "Unable to locate the VERSIONS file. Exit..."
        exit ${ST_ERR}
    fi
}

validate_git_bin() {
    if [[ "x${GIT_BIN}" == "x" ]]; then
        print_error "Unable to locate the git bin. Exit..."
        exit ${ST_ERR}
    fi
}

validate_php_bin() {
    if [[ "x${PHP_BIN}" == "x" ]]; then
        print_error "Unable to locate the php bin. Exit..."
        exit ${ST_ERR}
    fi
}

validate_composer_bin() {
    if [[ "x${COMPOSER_BIN}" == "x" ]]; then
        print_error "Unable to locate the composer bin. Exit..."
        exit ${ST_ERR}
    fi
}

install_app_deps() {
    validate_composer_bin

    pushd ${WORK_DIR} &> /dev/null

    ${COMPOSER_BIN} install \
        --quiet \
        --no-interaction \
        --no-ansi \
        --no-progress \
        --optimize-autoloader \
        --no-dev \
        --prefer-dist \
        --no-suggest \
        --ignore-platform-reqs

    popd &> /dev/null
}

print_versions() {
    validate_versions

    cat "${WORK_DIR}/VERSIONS"
}

update_docs() {
    validate_git_bin

    declare docs_path="${WORK_DIR}/docs"
    declare versions=$(print_versions)
    declare locales=$(print_loales_dirs)

    if [[ ! -d ${docs_path} ]]; then
        print_error "Unable to locate the docs base directory"
        exit ${ST_ERR}
    fi

    printf "Detected versions: " && echo ${versions}
    printf "\n"

    for version in ${versions}; do
        printf "Update the docs for ${version}...\n"

        if [[ -d "${docs_path}/${version}/.git" ]]; then
            printf "The ${version} version of docs already cloned. Try to update it...\n"
            cd "${docs_path}/${version}"

            pushd "${docs_path}/${version}" &> /dev/null

            declare locales=$(print_loales_dirs)

            ${GIT_BIN} checkout -f  &> /dev/null
            ${GIT_BIN} pull origin ${version}  &> /dev/null

            printf "Detected locales in the $version version: " && echo ${locales}
            printf "\n"
            for locale in ${locales}; do
                printf "Going to add missed docs for: ${docs_path}/${version}/${locale}...\n"
                cp -vR ${docs_path}/${version}/en/* ${docs_path}/${version}/${locale}/ > /dev/null 2>&1
            done

            printf "Discard unwanted changes in working directory: ${docs_path}/${version}\n"
            ${GIT_BIN} checkout -- .

            popd &> /dev/null
        else
            rm -rf "${docs_path}/${version}"
            mkdir -p "${docs_path}/${version}"
            ${GIT_BIN} clone -q -b ${version} --depth=1 "${DOCS_REPO}" "${docs_path}/${version}" &> /dev/null
        fi

        printf "Done\n\n"
    done
}

pull_latest_changes() {
    validate_git_bin

    declare current_branch=`${GIT_BIN} rev-parse --abbrev-ref HEAD`

    printf "Current branch is ${YELLOW}${current_branch}${NC}.\n"

    if [[ ${current_branch} != master ]]; then
        print_error "Doing nothing: only the master branch may be deployed for this project."
        exit ${ST_ERR}
    else
        printf "Pull the latest changes from the git repo...\n"

        pushd ${WORK_DIR} &> /dev/null

        ${GIT_BIN} checkout -f &> /dev/null
        ${GIT_BIN} pull origin ${current_branch} &> /dev/null

        popd &> /dev/null
    fi
}

for key in $@; do
    case ${key} in
        --help|-H)
            print_help
            exit ${ST_HLP}
            ;;
        --version|-V)
            print_version
            exit ${ST_HLP}
            ;;
        --dumpversion)
            print_dump_version
            exit ${ST_HLP}
            ;;
        --list-versions|-L)
            print_versions
            exit ${ST_HLP}
            ;;
        --clear-cache)
            CLEAR_CACHE=1
            shift
            ;;
        --no-clear-cache)
            CLEAR_CACHE=0
            shift
            ;;
        --install-deps)
            INSTALL_DEPS=1
            shift
            ;;
        --no-install-deps)
            INSTALL_DEPS=0
            shift
            ;;
        --update-docs)
            UPDATE_DOCS=1
            shift
            ;;
        --no-update-docs)
            UPDATE_DOCS=0
            shift
            ;;
        --pull-changes)
            PULL_CHANGES=1
            shift
            ;;
        --no-pull-changes)
            PULL_CHANGES=0
            shift
            ;;
        --working-dir=*)
            WORK_DIR="${key#*=}"
            shift
            ;;
        -*)
            # unknown option
            print_unknown_option $1
            exit ${ST_HLP}
            ;;
        *)
            # No more options
            break
            ;;
    esac
done

validate_work_dir

if [[ "${PULL_CHANGES}" -eq 1 ]]; then
    pull_latest_changes
fi

if [[ "${INSTALL_DEPS}" -eq 1 ]]; then
    install_app_deps
fi

if [[ "${UPDATE_DOCS}" -eq 1 ]]; then
    update_docs
fi

if [[ "${CLEAR_CACHE}" -eq 1 ]]; then
    printf "Clear the cache...\n"

    rm -f "${WORK_DIR}/storage/cache/config/*.php"

    validate_php_bin
    ${PHP_BIN} ${WORK_DIR}/phalcon -clear-cache

    printf "Done\n\n"
fi

exit ${ST_OK}
